﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using System.Web.Script.Serialization;

using Fuse8.DomainFramework.BusinessService;
using Fuse8.DomainFramework.Common.Locator;

using Fuse8.ContentManagementFramework.Domain.Special;
using Fuse8.ContentManagementFramework.Domain.Commands;
using Fuse8.ContentManagementFramework.Domain.Commands.CommandParameters;

namespace Fuse8.ContentManagementFramework.Domain
{
    public partial class CmsPage
    {
        public const string PagePropertyKey = "cmsPageProperty";
        public const string RedirectPropertyKey = "cmsRedirectProperty";
        
        private IEnumerable<CmsPageControl> _pageControls;
        private string _parentPageName;
        private CmsPage _previousSibling;
        private CmsPage _nextSibling;
        private CmsRedirectPageSetting redirectSetting;

        public CmsPageTypeKind CommonPageType
        {
            get
            {
                return (CmsPageTypeKind)Enum.ToObject(typeof(CmsPageTypeKind), PageTypeKey);
            }
        }

        public CmsPageBehaviourTypeKind BehaviourPageType
        {
            get
            {
                return (CmsPageBehaviourTypeKind)Enum.ToObject(typeof(CmsPageBehaviourTypeKind), PageBehaviourTypeKey);
            }
        }

        public string Title
        {
            get
            {
                return PageTitle ?? PageName;
            }
        }

        public override bool UseBuiltInFlow
        {
            get
            {
                return false;
            }
        }

        [XmlIgnore]
        [ScriptIgnore]
        public IEnumerable<CmsPageControl> PageControls
        {
            get
            {
                // note it is necessary to call ToList() to safely put _pageControls to cache or state server session
                if (_pageControls == null)
                {
                    var businessFacade = new BusinessServiceFacade<CmsPageControl, int>();

                    var command = DependencyServiceLocator.Current.GetInstance<CmsPageControlsGetByPageIdCommand>();

                    var commandParameter = new CmsPageControlsGetByPageIdCommandParameter
                                               {
                                                   PageId = Id,
                                                   IsInAdministrationArea =
                                                       DependencyServiceLocator.Current.GetInstance<ICmsContext>().
                                                       IsInAdministrationArea
                                               };

                    command.ConfigureCommand(commandParameter);

                    _pageControls = businessFacade.Find(command).ToList();
                }

                return _pageControls;
            }
            set
            {
                if (value != null)
                {
                    _pageControls = value.ToList();
                }
            }
        }
        
        public IEnumerable<CmsPageControl> this[CmsTemplateRegion region]
        {
            get
            {
                return region != null ?
                    PageControls.Where(p => p.TemplateRegionId == region.Id) :
                    new List<CmsPageControl>();
            }
        }

        [XmlIgnore]
        public string UserCreatedBy { get; set; }

        [XmlIgnore]
        public string UserLastUpdatedBy { get; set; }

        [XmlIgnore]
        public int ChildrenCount { get; set; }

        [XmlIgnore]
        public string ParentPageName
        {
            get
            {
                if (string.IsNullOrEmpty(_parentPageName) && ParentPage != null)
                {
                    _parentPageName = ParentPage.PageName;
                }

                return _parentPageName;
            }
            set
            {
                _parentPageName = value;
            }
        }

        [XmlIgnore]
        public CmsPage PreviousSibling
        {
            get
            {
                if (_previousSibling == null)
                {
                    //TO DO: implement
                }

                return _previousSibling;
            }
            set 
            {
                _previousSibling = value;
            }
        }

        [XmlIgnore]
        public CmsPage NextSibling
        {
            get
            {
                if (_nextSibling == null)
                {
                    //TO DO: implement
                }

                return _nextSibling;
            }
            set
            {
                _nextSibling = value;
            }
        }

        [XmlIgnore]
        public CmsRedirectPageSetting RedirectSetting
        {
            get { return redirectSetting ?? (redirectSetting = GetMetaValue<CmsRedirectPageSetting>(RedirectPropertyKey)); }
            set { redirectSetting = value; }
        }

        public bool IsUrlRequired
        {
            get
            {
                return BehaviourPageType == CmsPageBehaviourTypeKind.Content ||
                   BehaviourPageType == CmsPageBehaviourTypeKind.Redirect &&
                   (RedirectSetting.Type == PageRedirectKind.Redirect301 ||
                    RedirectSetting.Type == PageRedirectKind.Redirect302);
            }
        }
    }
}
